<template>
  <div ref="echartsRef" :style="{ width, height }" class="echarts-container"></div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
import * as echarts from 'echarts';
import type { ECharts, EChartsOption, PieSeriesOption } from 'echarts';

interface EchartsDataItem {
  name: string;
  value: number;
  itemStyle: {
    color: string;
  };
  clickData?: unknown;
}

interface Props {
  id?: string;
  title?: string;
  echartsData: EchartsDataItem[];
  height?: string;
  width?: string;
  unit?: string;
}

const props = withDefaults(defineProps<Props>(), {
  height: '100%',
  width: '100%',
  unit: 'km'
});

const emit = defineEmits<{
  (e: 'pipAgeClick', params: unknown): void;
}>();

const echartsRef = ref<HTMLElement | null>(null);
const myChart = ref<ECharts | null>(null);
let resizeObserver: ResizeObserver | null = null;

// 生成图表配置
const generateChartOption = (data: EchartsDataItem[]): EChartsOption => {
  const colors = data.map((item) => item.itemStyle.color);
  const seriesData = data.map((item) => ({
    name: item.name,
    value: item.value
  }));

  const total = data.reduce((sum, item) => sum + Number(item.value), 0);

  return {
    color: colors,
    tooltip: {
      position: [50, 50],
      formatter: (params: any) => {
        const percentage = ((params.value / total) * 100).toFixed(2);
        return `
          ${params.seriesName}<br/>
          <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params.color};"></span>
          ${params.name}占比: ${percentage}%<br/>
        `;
      }
    },
    legend: {
      orient: 'horizontal',
      left: 'center',
      bottom: 0,
      itemGap: 10,
      itemWidth: 10,
      itemHeight: 10,
      textStyle: {
        color: '#fff',
        fontSize: 13
      }
    },
    series: [
      {
        name: props.title,
        type: 'pie',
        radius: ['30%', '50%'],
        label: {
          formatter: `{c}${props.unit}`,
          fontSize: 13
        },
        data: seriesData,
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        }
      }
    ] as PieSeriesOption[]
  };
};

// 初始化图表
const initChart = () => {
  if (!echartsRef.value) return;

  disposeChart();
  myChart.value = echarts.init(echartsRef.value);
  updateChart();

  // 添加点击事件
  myChart.value.on('click', (params) => {
    emit('pipAgeClick', params);
  });
};

// 更新图表数据
const updateChart = () => {
  if (!myChart.value || !props.echartsData.length) return;

  const option = generateChartOption(props.echartsData);
  myChart.value.setOption(option);
};

// 销毁图表
const disposeChart = () => {
  if (myChart.value && !myChart.value.isDisposed()) {
    myChart.value.off('click');
    myChart.value.dispose();
  }
  myChart.value = null;
};

// 处理大小变化
const handleResize = () => {
  nextTick(() => {
    if (myChart.value && !myChart.value.isDisposed()) {
      myChart.value.resize();
    }
  });
};

// 初始化 ResizeObserver
const initResizeObserver = () => {
  if (!echartsRef.value) return;

  resizeObserver = new ResizeObserver(() => {
    handleResize();
  });
  resizeObserver.observe(echartsRef.value);
};

// 生命周期钩子
onMounted(() => {
  nextTick(() => {
    initChart();
    initResizeObserver();
  });
});

onUnmounted(() => {
  if (resizeObserver) {
    resizeObserver.disconnect();
    resizeObserver = null;
  }
  disposeChart();
  window.removeEventListener('resize', handleResize);
});

// 监听数据变化
watch(
  () => props.echartsData,
  (newData) => {
    if (newData.length) {
      updateChart();
    }
  },
  { deep: true }
);

// 监听尺寸变化
watch(
  () => [props.width, props.height],
  () => {
    handleResize();
  }
);
</script>

<style scoped>
.echarts-container {
  transition:
    width 0.3s,
    height 0.3s;
}
</style>
